﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataAnalyticsTools.Models
{

    /// <summary>
    /// 聚类结果
    /// </summary>
    public class ClusteringResult
    {
        /// <summary>
        /// 样本标签数组，长度等于样本数
        /// </summary>
        public int[] Labels { get; set; }

        /// <summary>
        /// 聚类中心坐标，形状为[簇数量, 特征数]
        /// </summary>
        public float[][] Centroids { get; set; }

        /// <summary>
        /// 轮廓系数数组，长度等于样本数
        /// </summary>
        public float[] SilhouetteScores { get; set; }

        /// <summary>
        /// 平均轮廓系数
        /// </summary>
        public float AverageSilhouetteScore => SilhouetteScores?.Average() ?? 0f;

        /// <summary>
        /// 使用的聚类算法
        /// </summary>
        public string Algorithm { get; set; }

        /// <summary>
        /// 迭代次数（适用于迭代算法）
        /// </summary>
        public int Iterations { get; set; }

        /// <summary>
        /// 是否收敛
        /// </summary>
        public bool ConvergenceReached { get; set; }

        /// <summary>
        /// 噪声点数量（适用于DBSCAN）
        /// </summary>
        public int NoisePoints { get; set; }

        /// <summary>
        /// 合并历史（适用于层次聚类）
        /// </summary>
        public List<ClusterMerge> MergeHistory { get; set; }

        public ClusteringResult(int[] labels, float[][] centroids, float[] silhouetteScores = null)
        {
            Labels = labels;
            Centroids = centroids;
            SilhouetteScores = silhouetteScores ?? new float[labels.Length];
            MergeHistory = new List<ClusterMerge>();
        }

        public string OverallQuality
        {
            get
            {
                return AverageSilhouetteScore switch
                {
                    >= 0.7f => "优秀",
                    >= 0.5f => "良好",
                    >= 0.3f => "一般",
                    >= 0.0f => "较差",
                    _ => "无效聚类"
                };
            }
        }

        public IEnumerable<Cluster> ToClusterList(float[][] features)
        {
            List<Cluster> finalResult = [];

            // 循环处理各样本
            for (int i = 0; i < this.Labels.Length; i++)
            {
                // 处理簇，没有追加的话，先插入
                if (!finalResult.Any(d => d.ClusterId == this.Labels[i]))
                {
                    finalResult.Add(new Cluster(this.Labels[i], this.Labels[i] == -1 ? null : this.Centroids[this.Labels[i]]));
                }

                // 处理样本
                var cluster = finalResult.First(d => d.ClusterId == this.Labels[i]);
                cluster.SilhouetteScores.Add(this.SilhouetteScores[i]);
                cluster.SampleIndices.Add(i);
                cluster.Samples.Add(features[i]);
            }

            return finalResult;
        }
    }
}
